home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 2: CDPD 1 / Almathera Ten on Ten - Disc 2: CDPD 1.iso / pd / 076-100 / 077 / quest / quest.doc < prev   
Text File  |  1995-03-13  |  17KB  |  356 lines

  1.                 Quest
  2.  
  3.  
  4.      Four files are included in Quest. Three provide independent
  5. libraries of useful utilities which are the framework of any Quest
  6. scenario. The fourth is a simple sample scenario. The sample scenario
  7. doesn't do anything, but does illustrate the use of the rest of the
  8. system, and provides a working demo of most of the facilities.
  9.  
  10.  
  11. qcrt.d - CRT routines.
  12.  
  13.      These routines handle a 24 line by 80 column screen. Even though the sizes
  14. are parameterized as constants (NLINES and NCOLUMNS), it is not likely that the
  15. code would work properly with a different size screen. All routines whose names
  16. begin with 'CRT_' are in my CRT library. The routines used are:
  17.  
  18.     CRT_Initialize(*char title; ushort nLines, nCols) - open a window
  19.     of given size and set its title
  20.     CRT_Terminate() - closes the window
  21.     CRT_ClearScreen() - clear the screen & leave cursor at (0, 0)
  22.     CRT_ClearLine(ushort line) - clear line & leave cursor at (line, 0)
  23.     CRT_Abort() - close window and return to system cleanly
  24.     CRT_Move(ushort line, column) - move the cursor to the indicated
  25.     (0-origin) line and column on the screen
  26.     CRT_EnterHighLight() - output after this will be highlighted, e.g.
  27.     in a different color
  28.     CRT_ExitHighLight() - output after this will be normal
  29.     CRT_ClearTail() - the current line from the cursor to the last
  30.     column is cleared - the cursor is not moved
  31.     CRT_ClearToEnd(ushort line) - the cursor is moved to the beginning
  32.     of the given line and the screen is cleared from there on down
  33.     CRT_PutChars(*char string) - the given string is output to the
  34.     screen at the current cursor position
  35.     CRT_PutChar(char ch) - the character is output to the screen
  36.     CRT_ReadChar()char - wait for and read a character from the terminal
  37.     CRT_GetLine(*char buffer; ushort length) - this routine reads an
  38.     input line of the given maximum length into the buffer. Input
  39.     line editing (backspace, line delete) is enabled.
  40.  
  41.      The upper left-hand corner of the screen, 11 lines by 38 columns, is
  42. used to display an 11 line by 19 column region of a "scenery map" which
  43. is a sort of bird's eye view of the region around the player character
  44. (PC) or group. Each 'cell' in the map is represented by two characters,
  45. side by side. The CRT routines maintain this view by calling a user-
  46. supplied scenery generator, which, given the line and column
  47. co-ordinate, returns the pair of characters to display for that position.
  48. Also maintained is a list of 'movable objects' which are not considered
  49. part of the scenery. Each has a pair of characters to display. They are
  50. displayed 'over top of' the scenery, and the last such specified at a
  51. given position is the one displayed. Each has an identifier by which the
  52. user programmer can refer to it. The one with identifier = 0 is assumed
  53. to be the PC or group, and if it is moved to or off of the edge of the
  54. viewing area, then the entire map view is windowed (which will entail a
  55. number of calls to the user-supplied scenery generator).
  56.  
  57.      The upper right-hand corner of the screen, 11 lines by 40 columns,
  58. is used to display various status indicators needed by the scenario.
  59. There are three kinds of status indicators: numeric, string and string-
  60. list. These are set up by calling the appropriate routine with a numeric
  61. identifier for the item, it's header string, it's position in the status
  62. area (line, column of the first character of the header), and the item's
  63. size. These routines are also passed the address of the actual variable
  64. which records the current value, so that a simple call to 'scUpdate' can
  65. update the status display directly. String-list items are used for
  66. things such as the list of things the PC is carrying - the update
  67. routine handles correct formatting for multi-line display with
  68. separating commas. Instead of being given the address of the list
  69. header, the 'scMult' routine is passed a procedure which it is to call
  70. to get successive strings to display.
  71.  
  72.      The bottom 12 lines of the screen are used for text input/output as
  73. occurs in most Adventure style games. When the bottom of the screen is
  74. reached, the area is cleared and I/O continues on the first line of the
  75. region. If the bottom is reached during output, then the output pauses
  76. until the end-user types a key to continue (my version displays 'MORE',
  77. highlighted, down the right-hand edge of the region). The output routine
  78. handles one character at a time. This allows me to use it as a Draco
  79. text output channel through which I can 'write' or 'writeln' whatever I
  80. need to output. Output in this way will automatically do word breaks at
  81. the correct place. (This means that, unless special output formats are
  82. needed, text can be output in one big continuous stream, and will be
  83. automagically broken on word boundaries.)
  84.  
  85.      All CRT routines have names beginning with 'sc'. They are:
  86.  
  87. Miscellaneous routines:
  88.  
  89. scInit() - this must be called once before any other calls.
  90.  
  91. scTerm() - called to free up resources used by CRT routines. This
  92.     also calls CRT_Terminate to terminate the entire program.
  93.  
  94. Map area routines:
  95.  
  96. scNewMap(proc(long line, column)[2]char scenery; *byte oldObj)*byte -
  97.     this fancy header indicates that 'scNewMap' has 2 parameters and
  98.     returns a result. The first parameter is a procedure which takes two
  99.     long integer parameters and returns an array of 2 characters - this
  100.     is the scenery generator mentioned above. The second parameter is
  101.     the list of "movable objects" associated with the map. This is
  102.     usually just 0, but is used when a scenario involves more than one
  103.     map (it preserves the "movable objects" between uses of the map).
  104.     The value returned is the "movable objects" list that used to be
  105.     active. This routine must be called before the map area is used for
  106.     anything.
  107.  
  108. scObjFree(*byte ol) - free any object list left behind from other map
  109.     areas by calls to scNewMap. The list currently active is freed by
  110.     scTerm.
  111.  
  112. scWindow(long line, column) - forces the map area to be redrawn, centered
  113.     on the given co-ordinates.
  114.  
  115. scNew(Id_t id; long line, column; [2]char chars) - this routine is used
  116.     to create a new "movable object". The id is used to refer to the
  117.     entry when moving or deleting it. The line and column are where the
  118.     object is now, and the two characters are what to display for it.
  119.  
  120. scAt(long line column)[2]char - return the pair of characters which is
  121.     currently displayed at the given position.
  122.  
  123. scMove(Id_t id; long line, column) - the specified "movable object" is
  124.     moved to the given location and redisplayed (if within the window).
  125.  
  126. scDelete(Id_t id) - the specified "movable object" is removed and can
  127.     no longer be referenced.
  128.  
  129. Status area routines:
  130.  
  131. scNumber(Id_t id; *char name; ushort line, column, length; *long ptr) -
  132.     this routine is used to create a numeric status display. 'name' is
  133.     the string to use for a header, 'line' and 'column' specify where in
  134.     the status area to display the item, 'length' is the number of
  135.     spaces to use for the numeric display (format is 'HEADER: xxxx'),
  136.     and ptr is the address of the variable which is being displayed. (
  137.     This address is saved away so that calls to 'scUpdate' can cause a
  138.     re-display without having to pass in the new value.)
  139.  
  140. scString(*d_t id; *char name; ushort line, column, length; **char ptr) -
  141.     this routine is used to create a string status display. 'length' is
  142.     the length of the string to be used (it will be padded on the right
  143.     or truncated as needed). 'ptr' points to the string variable.
  144.  
  145. scMult(Id_t id; *char name; ushort line, column, lines;
  146.        proc(bool first)*char gen) - this routine is used to create a
  147.     string-list status display. 'lines' is the number of lines reserved
  148.     for this item (successive lines start in the 3rd column of the
  149.     status display area). 'gen' is a procedure to call to get the items
  150.     to be displayed in the list. It has a parameter telling it to start
  151.     over since, if the items won't fit in the available space, the
  152.     display process will prematurely stop calling it. If the items won't
  153.     fit in the available lines, the last one is followed by '..' to
  154.     indicate that there were more items.
  155.  
  156. scUpdate(Id_t id) - the specified status item is re-displayed. Once the
  157.     display items are set up, this is the only display item routine that
  158.     will be needed.
  159.  
  160. Text I/O routines:
  161.  
  162. scPut(char ch) - this routine is called to output a character in the
  163.     text area. Word break and pagination is handled as discussed above.
  164.     The character '\n' (linefeed) are used to signal the need for a
  165.     forced newline.
  166.  
  167. scPrompt(*char prompt) - this routine is called to specify the prompt to
  168.     use on input.
  169.  
  170. scRead(*char buffer) - an input line is read into the passed buffer. If
  171.     any text was left to be output (it is buffered up to allow for the
  172.     word-break processing) it is output first and a new line started.
  173.     Any prompt is output before the read is done.
  174.  
  175.  
  176. qparse.d - the parser.
  177.  
  178.      The parser is fairly simple but will handle a variety of input
  179. styles, ranging from the simple 'get book' to the more complex 'Put the
  180. magic sword into the glass trophy case.' No provisions are currently
  181. present for having multiple commands on one line unless the grammar
  182. specifies it directly (quite cumbersome). Prefixes, consisting of words
  183. before an initial ':' can be picked off, but this facility will probably
  184. not be used (see later). These routines handle the dictionary, which
  185. contains words, along with their id (should be unique) and type (the
  186. parser places no interpretation on types, but they are needed). The
  187. words are stored directly as given (any characters can be used), but
  188. when the parsing occurs, case will be ignored. Also, when parsing,
  189. spaces are used as word separators, so having 'words' with spaces in
  190. them will not work.
  191.  
  192.      The grammar parsed consists of a number of sentence forms, each of
  193. which is simply a list of elements. An element can be a specific word
  194. which is required, a specific word-type which is required, an optional
  195. specific word, an optional word-type or a sequence of words of a given
  196. type. For example, the grammar sentence
  197.  
  198.     give [ARTICLE] ADJECTIVE* NOUN to [ARTICLE] ADJECTIVE* NOUN
  199.     [PUNCTUATION]
  200.  
  201. could be used to handle the verb 'give'. Input sentences like
  202.  
  203.     Give the big red rose to the ugly dwarf.
  204.     give sword to troll
  205.  
  206. would be accepted (provided the words were in the dictionary and had
  207. been flagged with the appropriate types). The various sentence forms are
  208. tried one at a time to match the input commands, thus the ones given
  209. first will take precedence over later ones in case of ambiguity.
  210.  
  211.     All parser routine names start with 'ps'. They are:
  212.  
  213. psInit(bool prefixEnabled) - must be called once before any other parser
  214.     routines are used. If 'prefixEnabled' is true, then prefixes ending
  215.     with ':' will be picked off of input sentences, otherwise they are
  216.     handled as part of the input sentence. Even when such prefixes are
  217.     used (e.g. to talk to NPC's), it is probably better to have separate
  218.     grammar rules for the things that can be said to NPC's, instead of
  219.     having these things mixed in with the rules for direct commands. The
  220.     whole area needs more thought.
  221.  
  222. psTerm() - called at the end of the run to free up space used by the
  223.     stored dictionary and grammar, and any working storage used by the
  224.     parser.
  225.  
  226. psWord(Id_t id; *char txt; Id_t typ) - the given word is added to the
  227.     dictionary with the given id and word-type. More than one entry with
  228.     the same id can be added - they are synonyms. Punctuation 'words'
  229.     are added in the same way.
  230.  
  231. psDel(Id_t id) - called to delete the specified word from the
  232.     dictionary.
  233.  
  234. psgBegin(Id_t id) - called to start the specification of a grammar
  235.     rule with the given id.
  236.  
  237. psgWord(PSForm_t form; Id_t data) - called to add an element to a grammar
  238.     rule. PSForm_t is an enumeration type with values f_reqId,
  239.     f_reqType, f_optId, f_optType, and f_multiple which is included in
  240.     q.g. The five element types were discussed above (required word of
  241.     given id, required word of given type, optional word of given id,
  242.     optional word of given type, multiple words of given type). The
  243.     'data' parameter is either the id or word-type, as needed.
  244.  
  245. psgEnd() - called to signal the end of a grammar rule. Grammar rules can
  246.     be added at any time, as can dictionary entries; thus the language
  247.     can grow as the game progresses.
  248.  
  249. psgDel(Id_t id) - delete the specified grammar rule from the grammar.
  250.  
  251. psFind(*char txt)Id_t - looks a word up in the dictionary. Returns the
  252.     id of the word, or 0 if the word isn't found (thus id = 0 should not
  253.     be used for any word).
  254.  
  255. psType(Id_t id)Id_t - returns the word-type of the identified word
  256.  
  257. psGet(Id_t id)*char - returns the text of the identified word
  258.  
  259. psParse(*char sentence)Id_t - this routine parses the given input string
  260.     according to the currently existing dictionary and grammar rules. It
  261.     returns: PS_ERROR if some word in the input is unknown (call pspBad
  262.     to get the text of the word); PS_BAD if all words were known but the
  263.     input didn't match any of the grammar rules; else the grammar rule
  264.     number of the matched rule For a successful match, 'pspWord' and
  265.     'pspPref' can be used to find more details.
  266.  
  267. pspBad()*char - called after pspParse has returned PS_ERROR to get the
  268.     text of the word which wasn't in the dictionary. (The parser stops
  269.     as soon as it finds one, so there will only be the one.)
  270.  
  271. pspWord(uint pos)Id_t - returns the id of the word(s) that matched the
  272.     'pos'th position in the successful grammar rule. For optional
  273.     elements, 0 is returned if no word was there. For multiple elements,
  274.     successive calls to 'pspWord' with the same 'pos' will return the
  275.     various words that matched. No more (or none at all) is signalled by
  276.     'pspWord' returning 0.
  277.  
  278. pspPref()Id_t - After psParse when prefixes are enabled, successive calls
  279.     to this routine will return the id's of the words that were part of
  280.     the prefix (the stuff before the first ':'). To handle prefixes like
  281.     'Dan, Joe:', comma should be made a word and will be dutifully
  282.     returned by pspPref. (The ':' is thrown away.) pspPref returns 0
  283.     when there are no more prefix words (if there were any at all).
  284.  
  285.  
  286. qlist.d - list handling routines.
  287.  
  288.      These routines are used for handling semantic information. They
  289. care nothing about meanings - they are just general tools. One set of
  290. routines (names start with 'l') simply handles lists of integers (
  291. adding, appending, deleting, etc.) Another set handles properties (
  292. essentially arbitrary boolean (true/false) flags) associated with
  293. identifiers. A third set handles attribute-value pairs associated with
  294. identifiers (things like (size 2), (weight 20), (color red), etc.).
  295.  
  296. lInit() - this routine must be called before any others in this set.
  297.  
  298. lFree(*List_t il) - called to free a list for the user program.
  299.  
  300. lTerm() - called to free up all list structures at end of run.
  301.  
  302. getId()Id_t - called to get a unique integer id. The values returned on
  303.     consecutive calls are just 1, 2, 3, etc. Note that this routine was
  304.     never used in the sample scenario program, since all id's were
  305.     needed to be known in several places.
  306.  
  307. Simple list handling routines.
  308.  
  309. Type List_t given in q.g defines the elements of the lists. A list
  310. variable is of type *List_t.
  311.  
  312. lAdd(**List_t pil; Id_t n) - the value 'n' is added to the front of the
  313.     list. No check is made to see if it is already in the list.
  314.  
  315. lAppend(**List_t pil; Id_t n) - the value 'n' is appended to the end of
  316.     the list. No check is made to see if it is already in the list.
  317.  
  318. lDelete(**List_t pil; Id_t n) - the first occurrence (if any) of the
  319.     value 'n' is deleted from the list.
  320.  
  321. lGet(*List_t il; ulong n)Id_t - the value of the n'th element of the list
  322.     is returned (if any, else 0).
  323.  
  324. lIn(*List_t il; Id_t n)bool - returns 'true' if the value 'n' is in the
  325.     list, else returns 'false'.
  326.  
  327. Property handling routines.
  328.  
  329. putProp(Id_t id, prop) - associates property 'prop' with item 'id'.
  330.  
  331. getProp(Id_t id, prop)bool - returns 'true' if property 'prop' is
  332.     associated with item 'id', else returns 'false'.
  333.  
  334. delProp(Id_t id, prop) - ensures that property 'prop' is not associated
  335.     with item 'id'.
  336.  
  337. Attribute-value handling routines.
  338.  
  339. putAttr(Id_t id, attr, val) - associates attribute 'attr' with value
  340.     'val' with item 'id'. Any previous association is replaced.
  341.  
  342. getAttr(Id_t id, attr)Id_t - returns the value for attribute 'attr'
  343.     associated with item 'id', else 0 if none.
  344.  
  345. delAttr(Id_t id, attr) - dissassociates attribute 'attr' from item 'id'.
  346.  
  347.  
  348. qmain.d - sample scenario.
  349.  
  350.      If you are going to study any of the Quest source files, it should
  351. be this one. Writing a scenario does not require studying of the others,
  352. but this one is a must. I won't describe here what it does, but instead
  353. refer you to the comments in the file itself. You may have to refer back
  354. to the above descriptions, so you'll probably want to load the two files
  355. into an editor and read them that way.
  356.